using System;
using System.Reflection;
using OptionParser;
using DataFile;
using PGPlot;

[assembly: AssemblyTitle ("DataPlot")]
[assembly: AssemblyVersion ("1.0.*")]
[assembly: AssemblyDescription ("Plot data file using PGPlot.")]
[assembly: AssemblyCopyright ("2005 Joseph D. MacMillan")]

public class DataPlotOptions : InputGetOptions
{
    [Option ("-d", "The PGPlot device.")]
    public string Device;
    
    [Option ("-x", "The column to use for the x-axis.")]
    public int XCol;
    
    [Option ("-y", "The column to use for the y-axis.")]
    public int YCol;
    
    [Option ("-s", "The symbol to draw the points with.")]
    public int Symbol;
    
    [Option ("-c", "Connect the data points rather than drawing points.")]
    public bool Connect;
    
    [Option ("-l", "Limits")]
    public string Limits = "";
    
    [Option ("-xbox", "X-axis box options.")]
    public string XBoxOpts;
    
    [Option ("-ybox", "Y-axis box options.")]
    public string YBoxOpts;
    
    [Option ("-xlabel", "X-axis label.")]
    public string XLabel;
    
    [Option ("-ylabel", "Y-axis label.")]
    public string YLabel;
    
    [Option ("-all", "Plot all columns on the graph")]
    public bool All = false;
    
    public DataPlotOptions()
    {
        Device = "/xs";
        XCol = 1;
        YCol = 2;
        Symbol = 0;
        XBoxOpts = "bcnst";
        YBoxOpts = "bcnstv";
        XLabel = "";
        YLabel = "";
    }
}

public class DataPlot
{
    public static void Main(string[] args)
    {
        DataPlotOptions opts = new DataPlotOptions();
        opts.ProcessArgs(args);
        
        Table data = Table.Read(opts.InFile);
        
        Plot plot = new Plot(opts.Device);
        
        plot.SetViewport(0.15, 0.85, 0.15, 0.85);
        
        double x1, x2, y1, y2;
        if (opts.Limits != "")
        {
            string[] words = opts.Limits.Split(null);
            if (words.Length != 4)
            {
                throw new ApplicationException("Can't parse limits; must be in form \"x1 x2 y1 y2\"");
            }
            x1 = Double.Parse(words[0]);
            x2 = Double.Parse(words[1]);
            y1 = Double.Parse(words[2]);
            y2 = Double.Parse(words[3]);
        }
        else
        {
            double xmin = data.Minimum(opts.XCol - 1);
            double xmax = data.Maximum(opts.XCol - 1);
            double ymin = data.Minimum(opts.YCol - 1);
            double ymax = data.Maximum(opts.YCol - 1);
        
            x1 = xmin - 0.05 * (xmax - xmin);
            x2 = xmax + 0.05 * (xmax - xmin);
            y1 = ymin - 0.05 * (ymax - ymin);
            y2 = ymax + 0.05 * (ymax - ymin);
        }
        
        plot.SetLimits(x1, x2, y1, y2);
        
        plot.Box(opts.XBoxOpts, opts.YBoxOpts);
        if (opts.Connect)
            plot.Line(data.Column(opts.XCol - 1), data.Column(opts.YCol - 1));
        else
            plot.Points(data.Column(opts.XCol - 1), data.Column(opts.YCol - 1), opts.Symbol);
            
        if (opts.All)
        {
            int color = 1;
            for (int i = 0; i < data.Columns; i++)
            {
                if (i != (opts.XCol-1) && i != (opts.YCol-1))
                {
                    plot.Color = ++color;         
                    if (opts.Connect)
                        plot.Line(data.Column(opts.XCol - 1), data.Column(i));
                    else
                       plot.Points(data.Column(opts.XCol - 1), data.Column(i), opts.Symbol);
                }
            }
        }
            
        if (opts.XLabel != "")
            plot.XLabel(opts.XLabel);
        if (opts.YLabel != "")
            plot.YLabel(opts.YLabel);   
        
    }
}
